package com.china.produce.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.*;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.*;

/**
 * @ClassName
 *
 * @Author niujie
 * @Version
 * @Description
 * @CreateTime 2022/9/11
 */
@RequestMapping("/es")
@RestController
public class EsController {

    @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    @Qualifier("restSimpleEsClient")
    private RestClient restSimpleEsClient;

    /**
     * "settings":{
     *      "number_of_shards": 3,
     *      "number_of_replicas": 2
     * },
     * "mapping": {
     *
     * }
     *
     *
     * @param indexName
     * @return
     */
    @ApiOperation(value = "创建索引")
    @PostMapping("/createIndex/{indexName}")
    public String createIndex(@PathVariable("indexName") String indexName) {

        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);

        Settings build = Settings.builder()
                .put("index.number_of_shards", 3)
                .put("index.number_of_replicas", 1)
                .build();
        createIndexRequest.settings(build);

        // 设置索引映射（可选）
        Map<String, Object> jsonMap = new HashMap<>();
        Map<String, Object> properties = new HashMap<>();
        properties.put("product_id", Collections.singletonMap("type", "keyword"));
        HashMap<String, Object> dateFieldMapping = new HashMap<>();
        dateFieldMapping.put("type", "date");
        dateFieldMapping.put("format", "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
        properties.put("order_date", dateFieldMapping);
        properties.put("amount", Collections.singletonMap("type", "float"));
        jsonMap.put("properties", properties);
        createIndexRequest.mapping(jsonMap);

        try {
            CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);

            return "创建索引 " + indexName + " " + createIndexResponse.isAcknowledged();
        }catch (IOException exception) {

        }

        return null;
    }

    @ApiOperation(value = "创建索引")
    @PostMapping("/createIndexOfSimpleClient")
    public String createIndexOfSimpleClient() {
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPut putRequest = new HttpPut("http://81.69.242.110:9200/async_context");
            String jsonString =  "{\"settings\": {\"number_of_shards\": 1, \"number_of_replicas\": 1}}" + "{\"mappings\": {\"properties\": {\"my_field\": {\"type\": \"text\",\"fields\": {\"keyword\": {\"type\": \"keyword\",\"ignore_above\": 256}}}}}}";
            putRequest.setEntity(new StringEntity(jsonString, "UTF-8"));
            putRequest.setHeader("Content-Type", "application/json");
            CloseableHttpResponse response = httpClient.execute(putRequest);
            HttpEntity responseEntity = response.getEntity();
            String responseString = EntityUtils.toString(responseEntity, "UTF-8");

            return responseString;
        }catch (Exception exception) {
            System.out.println(exception.getMessage());
        }
        return "123";
    }

    @ApiOperation(value = "删除索引")
    @DeleteMapping("/deleteIndex/{indexName}")
    public String deleteIndex(@PathVariable("indexName") String indexName) throws IOException{
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);

        AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);

        return "删除索引 " + indexName + " " + acknowledgedResponse.isAcknowledged();
    }

    /**
     * 添加文档
     *
     * @param indexName
     * @throws IOException
     */
    @ApiOperation(value = "添加文档")
    @PostMapping("/add/document/{indexName}")
    public String addDoc(@PathVariable("indexName") String indexName) throws IOException
    {

        IndexRequest indexRequest = new IndexRequest(indexName);

        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        builder.field("product_id", "130");
        builder.field("order_date", "2025-04-19");
        builder.field("amount", "160");
        builder.endObject();
        indexRequest.source(builder);

        IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);

        return index.status() + " success !";
    }

    @ApiOperation(value = "分词器")
    @PostMapping("/analyzeRequest/{indexName}")
    public void analyzeRequest(@PathVariable("indexName") String indexName) throws IOException {

        AnalyzeRequest analyzeRequest = AnalyzeRequest.withGlobalAnalyzer("ik_smart", "你好呀,吃饭了吗？hello");

        AnalyzeResponse response = restHighLevelClient.indices().analyze(analyzeRequest, RequestOptions.DEFAULT);
        List<AnalyzeResponse.AnalyzeToken> tokens = response.getTokens();
        tokens.forEach(token -> {
            System.out.println("term: " + token.getTerm() +
                    ", position: " + token.getPosition() +
                    ", start_offset: " + token.getStartOffset() +
                    ", end_offset: " + token.getEndOffset() +
                    ", type: " + token.getType() +
                    ", positionLength: " + token.getPositionLength());
        });
    }

    @GetMapping("/search2/document/{indexName}")
    public String search2(@PathVariable("indexName") String indexName) throws IOException {
        String headString = "{\"index\":\"orders\"}" + System.lineSeparator();
        String dslString = "{\"size\": 5,\"query\": {\"match\": {\"amount\": \"160\"}}}" +  System.lineSeparator();
        StringBuffer stringBuffer = new StringBuffer();
        String body = stringBuffer.append(headString).append(dslString).toString();

        try {
            Request request = new Request("POST", "_msearch");
            StringEntity entity = new StringEntity(body, ContentType.APPLICATION_JSON);
            request.setEntity(entity);
            Response response = (Response) restSimpleEsClient.performRequest(request);
            HttpEntity responseEntity = response.getEntity();
            String responseString = EntityUtils.toString(responseEntity);
            JSONObject jsonObject = JSONObject.parseObject(responseString);
            jsonObject.getJSONArray("responses").forEach(responseObject -> {
                responseObject = (JSONObject) responseObject;
                JSONArray hits = ((JSONObject) responseObject).getJSONObject("hits").getJSONArray("hits");
                System.out.println(JSONObject.toJSONString(hits));
            });

        }catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return null;
    }


    @ApiOperation(value = "搜索文档")
    @GetMapping("/search/document/{indexName}")
    public String search(@PathVariable("indexName") String indexName) throws IOException {
        //searchSource
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.wildcardQuery("name", "document"));
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(5);
        ///searchSourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.DESC));
        searchSourceBuilder.query(boolQueryBuilder);

        //searchRequest
        SearchRequest searchRequest = new SearchRequest(indexName);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searches = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        ArrayList<Map<String, Object>> res = Lists.newArrayList();
        for (SearchHit hit : searches.getHits().getHits()) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            res.add(sourceAsMap);
        }

        return JSON.toJSONString(res);
    }

    @ApiOperation(value = "获取文档")
    @GetMapping("/get/document/{indexName}")
    public String getDoc(@PathVariable("indexName") String indexName) throws IOException {
        System.out.println(" " + indexName);
        GetRequest getRequest = new GetRequest(indexName, "1");

        GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);

        return response.getSourceAsString();
    }


}
